home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Utilities / WhosOnFirst / Source / myMainObject.m < prev    next >
Encoding:
Text File  |  1994-05-23  |  8.9 KB  |  359 lines

  1. #import "myMainObject.h"
  2. #import <appkit/appkit.h>
  3. #import <streams/streams.h>
  4. #import <utmp.h>
  5. #import <sys/param.h>
  6. #import <dpsclient/dpsNeXT.h>
  7.  
  8. extern id infoManager;
  9. int find();
  10. void enter();
  11. void clear_marks();
  12. void remove_unmarked();
  13.  
  14. /*===========================================================================
  15.  
  16.     File: myMainObject.m
  17.     Purpose:  This file replaces the file "myApp.m" in the previous 
  18.         version.  3.0 doesn't like sub-classes of NXApp.
  19.         This object does the work for determining who is on-line.
  20.         This object receives the appDidInit method signals other 
  21.         objects that this event occured.
  22.  
  23.     NOTE: All areas of code which deal with the TextToSpeech Kit have 
  24.         been put under conditional compilation.  If you do not 
  25.         have the TextToSpeech kit, simply comment out the flags 
  26.         in the Makefile.preamble file and this code should compile
  27.         for you.
  28.  
  29. ===========================================================================*/
  30.  
  31.  
  32. @implementation myMainObject
  33.  
  34. void who(DPSTimedEntry teNumber, double now, char *userData)
  35.  
  36. /* Call this function via the DPS Timed Entry */
  37.  
  38. {
  39. struct utmp temp;            /* Utmp structure. See utmp.h */
  40. char tempHost[MAXHOSTNAMELEN];
  41.  
  42.     clear_marks();                    /* Clear marked */
  43.     utmpFile = NXMapFile("/etc/utmp", NX_READONLY);    /* Map utmp file into memory */
  44.     if (utmpFile == NULL)
  45.     {
  46.         exit(0);
  47.     }
  48.     while( NXRead(utmpFile, &temp, sizeof(struct utmp)) !=0 )    /* Read next entry */
  49.     {
  50.         if (temp.ut_name[0] != '\000')                    /* Is is a real user? */
  51.         {
  52.             if (strlen(temp.ut_host)==0)
  53.             {
  54.                 gethostname(tempHost, MAXHOSTNAMELEN);
  55.                 enter(temp.ut_line, temp.ut_name, tempHost);    /* Yes, enter or affirm in list */
  56.             }
  57.             else
  58.                 enter(temp.ut_line, temp.ut_name, temp.ut_host);    /* Yes, enter or affirm in list */
  59.         }
  60.     }
  61.     remove_unmarked();                    /* Remove all un-referenced entries in 
  62.                                    the list */
  63.  
  64.     NXClose(utmpFile);                    /* Close utmp file */
  65. }
  66.  
  67. -appDidInit:sender
  68. {
  69. #ifdef SPEECH
  70. const char *appPath;
  71. char dictPath[256];
  72. #endif
  73.     /* Init Icon Position coordinates */
  74.     nextX = nextY = 0;
  75.  
  76.     /* Initialize List pointers */
  77.     last = users = NULL;
  78.  
  79.     /* Fudge.  C calls seem to need this */
  80.     c_self = self;
  81.  
  82.     DPSAddTimedEntry((double)5.0, (DPSTimedEntryProc) who, NULL, NX_BASETHRESHOLD);
  83.     infoManager = localInfoMgr;
  84.  
  85.     /* Read in Defaults */
  86.     [infoManager initDefaults];
  87.  
  88. #ifdef SPEECH
  89.     /* Get application directory and set up TTS Kit application dictionary */
  90.     appPath = [self appDirectory];
  91.     strcpy(dictPath, appPath);
  92.     strcat(dictPath, "/WhosOnFirst.preditor");
  93.  
  94.     /* Initialize the speech. Include the application dictionary.*/
  95.     [infoManager initSpeech:dictPath];
  96. #endif
  97.  
  98.     return(self);
  99. }
  100.  
  101. /*===========================================================================
  102.  
  103.     Method: appDirectory
  104.     Purpose: To determine the current working directory of this
  105.         application.  The TextToSpeech application dictionary is
  106.         located within WhosOnFirst.app.  To install this dictionary
  107.         into the search path of the TextToSpeech Kit, we must provide
  108.         the speech server with the full path.
  109.  
  110. ===========================================================================*/
  111.  
  112. -(const char *) appDirectory
  113. {
  114. static char appDirectory[256];
  115. FILE *process;
  116. char command[256];
  117. char *suffix;
  118.  
  119.     strcpy(appDirectory, NXArgv[0]);
  120.     if (appDirectory[0] == '/')
  121.     {               /* if absolute path */
  122.         if (suffix = rindex(appDirectory, '/'))
  123.             *suffix = '\000';                   /* remove executable name */
  124.     } 
  125.     else
  126.     {
  127.         sprintf(command, "which '%s'\n", NXArgv[0]);
  128.         process = popen(command, "r");
  129.         fscanf(process, "%s", appDirectory);
  130.         pclose(process);
  131.         if (suffix = rindex(appDirectory, '/'))
  132.             *suffix = '\000';                   /* remove executable name */
  133.         chdir(appDirectory);
  134.         getwd(appDirectory);
  135.     }
  136.     return ( (const char *) appDirectory);
  137. }
  138.  
  139. /*===========================================================================
  140.  
  141.     Method: newIconUser: name
  142.         tty: ttystr
  143.         host: hoststr
  144.         xcoord: x
  145.         ycoord: y
  146.  
  147.     Purpose: When a new user is detected, this method creats an icon
  148.         for him/her and puts the utmp information within its own
  149.         database.
  150.  
  151. ===========================================================================*/
  152.  
  153. -newIconUser: (const char *)name tty: (const char *)ttystr host: (const char *) hoststr xcoord: (float)x ycoord: (float)y
  154. {
  155. NXRect windowRect;
  156.  
  157.  
  158. #ifdef SPEECH
  159.     /* Tell infoManager to Speak */
  160.     [infoManager speakLoginMessage: name tty:ttystr host:hoststr];
  161. #endif
  162.  
  163.     iconWindow = [Window alloc];            /* Get a window instance */
  164.  
  165.     /* Calulate Screen Coordinates */
  166.     windowRect.origin.x = 4.0 + 64.0 * x;
  167.     windowRect.origin.y = 0.0 + 64.0 * y;
  168.     windowRect.size.height = windowRect.size.width = 64.0; /* Icon size 64x64 */
  169.  
  170.     /*Init the window content */
  171.     [iconWindow initContent: &windowRect style: NX_PLAINSTYLE
  172.          backing: NX_BUFFERED buttonMask:0  defer: YES];
  173.  
  174.     /* Get an IconView Instance */
  175.     icon = [[IconView alloc] init];
  176.  
  177.     /* Set IconView as the window's contentView */
  178.     [[iconWindow setContentView: icon] free];
  179.  
  180.     [iconWindow setDelegate:icon];        /* Make view the window's delegate */
  181.     [iconWindow makeFirstResponder:icon];    /* and first responder */
  182.  
  183.     [iconWindow addToEventMask:NX_MOUSEDOWNMASK];
  184.     
  185.     /* Add to window list */
  186.     [iconWindow makeKeyAndOrderFront:self];    
  187.  
  188.     [icon iconSetName: name];        /* Set icon variables */
  189.     [icon iconSetTty: ttystr];
  190.     [icon iconSetHostName: hoststr];
  191.  
  192.     return iconWindow;
  193. }
  194.  
  195. /*===========================================================================
  196.  
  197.     Method: terminate:sender
  198.  
  199.     Purpose:  The terminate method is sent here.  This object notifies 
  200.         other objects that the program is about to terminate
  201.  
  202. ===========================================================================*/
  203.  
  204. - terminate:sender
  205. {
  206.     [infoManager cleanUp];
  207.     [owner terminate:sender];
  208.     return self;
  209. }
  210.  
  211. /*===========================================================================
  212.  
  213.     Function: enter (tty, name, hostname)
  214.  
  215.     Purpose:  When a new user is detected, information about his/her
  216.         tty, login name, and hostname are kept in a small database.
  217.         This function enters the user information into the 
  218.         data structures.
  219.  
  220.     Structure: The data base is a simple linked-list.
  221.  
  222. ===========================================================================*/
  223.  
  224. void enter(tty,name, hostname)
  225. char *tty, *name, *hostname;
  226. {
  227. struct record *temp;
  228.  
  229.  
  230.     if (find(tty, name)==0)        /* If new entry, malloc space and put in list */
  231.     {
  232.         temp = (struct record *) malloc(sizeof (struct record ));
  233.         temp->next = NULL;
  234.  
  235.         /* New Icon */
  236.         temp->windowPointer = [c_self newIconUser: name tty: tty host: hostname
  237.                       xcoord: (float)nextX ycoord:(float) nextY];
  238.  
  239.         temp->x = (float)nextX;    /* Position Icon in "dock" */
  240.         temp->y = (float)nextY;
  241.         temp->marked = 1;    /* Mark icon as referenced */
  242.  
  243.         strcpy(temp->name, name);          /* User name */
  244.         temp->name[8] = '\000';
  245.         strcpy(temp->tty, tty);               /* TTY name */
  246.         strcpy(temp->hostname, hostname);    /* Hostname */
  247.  
  248.         if (last == NULL)    /* First entry in list (usually console) */
  249.         {
  250.             users = temp;
  251.             last = temp;
  252.         }
  253.         else            /* Not first entry in list */
  254.         {
  255.             last->next = temp;
  256.             last = temp;
  257.         }
  258.  
  259.         nextY++;        /* Update coordinate for next icon */
  260.         if (nextY>=12)
  261.         {
  262.             nextY = 0;
  263.             nextX++;
  264.         }
  265.     }
  266. }
  267.  
  268. void clear_marks()        /* Simply traverse list and clear "marked" item in struct */
  269. {
  270. struct record *temp;
  271.  
  272.     temp = users;
  273.     while (temp!=NULL)
  274.     {
  275.         temp->marked = 0;
  276.         temp = temp->next;
  277.     }
  278. }
  279.  
  280. void remove_unmarked()        /* Remove all items from the list which have not been referenced */
  281. {
  282. struct record *temp,*prev;
  283.  
  284.     nextX = nextY = 0;
  285.     temp = users;
  286.     prev = temp;
  287.     while (temp!=NULL)
  288.     {
  289.         if (temp->marked == 0)             /* Standard linked list removal algorithm */
  290.         {
  291.  
  292. #ifdef SPEECH
  293.             [infoManager speakLogoutMessage: temp->name tty:temp->tty host:temp->hostname];
  294. #endif
  295.             if (temp == users)        /* Remove head item */
  296.             {
  297.                 users = temp->next;
  298.                 [temp->windowPointer free];
  299.                 free(temp);
  300.                 temp = users->next;
  301.             }
  302.             if (temp == last)        /* Remove last item */
  303.             {
  304.                 last  = prev;
  305.                 prev -> next = NULL;
  306.                 [temp->windowPointer free];
  307.                 free(temp);
  308.                 temp = NULL;
  309.             }
  310.             else                /* Remove internal item */
  311.             {
  312.                 prev->next = temp->next;
  313.                 [temp->windowPointer free];
  314.                 free(temp);
  315.                 temp = prev->next;
  316.             }
  317.         }
  318.         else
  319.         {
  320.             temp->x = 4.0 + 64.0 * (float) nextX;    /* Calulate Screen Coordinates */
  321.             temp->y = 0.0 + 64.0 * (float) nextY;
  322.  
  323.             /* Reposition icon to new location */
  324.             [temp->windowPointer moveTo: temp->x : temp->y];
  325.             [[temp->windowPointer contentView] display];
  326.  
  327.             nextY++;    /* Calculate next icon position */
  328.             if (nextY>=12) 
  329.             {
  330.                 nextY = 0;
  331.                 nextX++;
  332.             }
  333.             prev = temp;
  334.             temp = temp->next;
  335.         }
  336.     }
  337. }
  338.  
  339. int find(tty,name)    /* Return a 1 if record with "name" and "tty" exists in the list */
  340.             /* Mark record as referenced so that it is not removed from the list */
  341. char *tty,*name;
  342. {
  343. struct record *temp;
  344.  
  345.     temp = users;        /* Head of list */
  346.     while(temp!=NULL)
  347.     {
  348.         if ((strncmp(temp->tty, tty,8)==0)&&(strncmp(temp->name,name,8) ==0))
  349.         {
  350.             temp->marked = 1;
  351.             return(1);
  352.         }
  353.         temp = temp->next;
  354.     }
  355.     return(0);
  356. }
  357.  
  358. @end
  359.